CHARTS
Don’t call the world dirty because you forgot to clean your glasses…
— Aaron Hill
# data preparation
germany <- election_data %>%
filter(year == 2017 & country == "Germany")
germany <- parliament_data(election_data = germany,
parl_rows = 10,
type = 'semicircle',
party_seats = germany$seats)
# make plot
bundestag <- ggplot(germany, aes(x, y, colour = party_short)) +
geom_parliament_seats(size = 3) +
labs(colour="Party") +
theme_ggparliament(legend = TRUE) +
scale_colour_manual(values = germany$colour,
limits = germany$party_short)
girafe(ggobj = bundestag, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# data preparation
uk_17 <- election_data %>%
filter(country == "UK" & year == "2017") %>%
parliament_data(election_data = .,
party_seats = .$seats,
parl_rows = 12,
type = "opposing_benches",
group = .$government)
# make plot
commons <- ggplot(uk_17, aes(x, y, colour = party_short)) +
geom_parliament_seats(size = 3) +
theme_ggparliament() +
coord_flip() +
labs(colour = NULL,
title = "UK parliament in 2017") +
scale_colour_manual(values = uk_17$colour,
limits = uk_17$party_short)
girafe(ggobj = commons, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# data preparation
russia_classroom <- election_data %>%
filter(country == "Russia" &
house == "Duma" &
year == 2016) %>%
parliament_data(election_data = .,
party_seats = .$seats,
parl_rows = 11,
type = "classroom")
# make plot
rus <- ggplot(russia_classroom, aes(x, y, colour = party_short)) +
geom_parliament_seats() +
theme_ggparliament() +
labs(
colour = NULL,
title = "Russian Duma") +
scale_colour_manual(
values = russia_classroom$colour,
limits = russia_classroom$party_short) +
theme(legend.position = "bottom")
girafe(ggobj = rus, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# data preparation
russia_circle <- election_data %>%
filter(country == "Russia" &
house == "Duma" &
year == 2016) %>%
parliament_data(election_data = .,
party_seats = .$seats,
parl_rows = 11,
type = "circle")
# make plot
russia_circle_example <- ggplot(russia_circle, aes(x, y, colour = party_short)) +
geom_parliament_seats() +
theme_ggparliament() +
scale_colour_manual(
values = russia_circle$colour,
limits = russia_circle$party_short) +
labs(colour = NULL) +
theme(legend.position = "bottom")
girafe(ggobj = russia_circle_example, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# data preparation
australia <- election_data %>%
filter(country == "Australia" &
house == "Representatives" &
year == 2016)
australia_horseshoe <- parliament_data(election_data = australia,
party_seats = australia$seats,
parl_rows = 4,
type = "horseshoe")
# make plot
au <- ggplot(australia_horseshoe, aes(x, y, colour = party_short)) +
geom_parliament_seats() +
theme_ggparliament() +
labs(colour = NULL,
title = "Australian Parliament") +
scale_colour_manual(values = australia$colour,
limits = australia$party_short) +
theme(legend.position = 'bottom')
girafe(ggobj = au, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# Take preliminary data as provided in ggparliament
data <- election_data %>%
filter(year == "2016" & country == "USA" & house == "Representatives")
usa_data <- parliament_data(election_data = data, type = "semicircle", party_seats = data$seats, parl_rows = 8)
# The Center for American Women and Politics provides statistics concerning women in U.S. politics
# See http://www.cawp.rutgers.edu/women-us-congress-2018 for more information.
# We create a binary variable -- women are 1, men are 0 -- for each party. Remember, the plot starts from the left hand side and finishes at the right hand side of the legislature. Given that we want to compare the two parties, it makes sense for them to be roughly parallel.
women_in_congress <- c(1, 0, 0, 1)
# The number of women in US congress - 23 Reps, 61 Dems. The two middle numbers are the remainder (i.e., number of men).
number_of_women <- c(23, 218, 133, 61)
# Use rep and mutate to append the binary female variable to the long data set.
usa_data <- usa_data %>% mutate(women = rep(women_in_congress, number_of_women))
# Plot the US congress as normal using geom_parliament_seats
women_in_congress <- ggplot(usa_data, aes(x, y, color=party_long)) +
geom_parliament_seats() +
# emphasize the women in each political party -- this must be specified in order for it to work!
geom_emphasize_parliamentarians(women == 1) +
draw_majoritythreshold(n = 218, label = FALSE, linecolour = "black", type = 'semicircle') +
draw_partylabels(type = 'semicircle', party_seats = seats, party_names = party_short, party_colours = colour) +
theme_void() +
theme(plot.title = element_text(hjust = 0.5),
legend.position = "none") +
scale_colour_manual(values = usa_data$colour, limits = usa_data$party_long) +
annotate(geom = "text", x = 0, y = 0.2, label = "61 Democrats in Congress\n are women. Only 23\nelected Republicans are women.") +
labs(title = "Women in 115th U.S. Congress")
girafe(ggobj = women_in_congress, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# data preparation
uk <- election_data %>%
filter(country == "UK") %>%
split(.$year) %>%
map(~parliament_data(election_data = .,
party_seats = .$seats,
group = .$government,
type = "opposing_benches")) %>%
bind_rows()
# make plot
uk_opposing_benches <- ggplot(data = uk,
aes(x = x,
y = y,
color = party_long)) +
geom_parliament_seats(size = 1.5) +
coord_flip() +
facet_wrap(~year, ncol = 2) +
scale_color_manual(values = uk$colour,
limits = uk$party_long) +
theme_ggparliament()
girafe(ggobj = uk_opposing_benches, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# load data
df <- read.csv('archetypes/ukrainian-parliament-of-the-9th-convocation.csv')
df1 <- df%>%group_by(Party)%>%summarise(Seats=sum(Seats))%>%arrange(Seats)
df1$legend <- paste0(df1$Party," (", df1$Seats,")")
# set colors manually
colors <- c("#cdd41f","#55a8ce","#c4ba7b","#d2044d","#f75914","#c3537f","#92b6be","#b3a3fa","#26aa5e")
# draw a parliament diagram
ukrainian_parliament <- ggplot(df1) +
geom_parliament(aes(seats = Seats, fill = Party), color = "white") +
scale_fill_manual(values = colors , labels = df1$legend) +
coord_fixed() +
theme_void() +
labs(title = "Ukrainian Parliament of the 9th convocation",
subtitle = "The number and distribution of seats in the Verkhovna Rada of Ukraine",
caption = "Source: https://rada.gov.ua | DataVizStory, 2020") +
theme(title = element_text(size = 18),
plot.title = element_text(hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5),
plot.caption = element_text(vjust = -3, hjust = 0.9),
legend.position = 'bottom',
legend.direction = "horizontal",
legend.spacing.y = unit(0.1, "cm"),
legend.spacing.x = unit(0.1, "cm"),
legend.key.size = unit(0.8, 'lines'),
legend.text = element_text(margin = margin(r = 1, unit = 'cm')),
legend.text.align = 0) +
annotate("text", x = 0, y = 0.4, label = "Seats in the Parliament :\n 423 occupied \n 27 vacant", colour = "black",size=6) +
guides(fill=guide_legend(nrow=3, byrow=TRUE, reverse=TRUE, title=NULL))
girafe(ggobj = ukrainian_parliament, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
# data preparation
df1 <- df%>%group_by(Party)%>%summarise(Seats=sum(Seats))%>%arrange(Seats)
df1$legend <- paste0(df1$Party, " (", df1$Seats, ")")
colors <- c("Trust group" = "#eb4570",
"Voice" = "#ed6327",
"Non-affiliated" = "#c8d0ac",
"For the Future group" = "#6a079a",
"Batkivshchyna" = "#d02b44",
"European Solidarity" = "#4a9dcc",
"Vacant seats" = "#bca7b5",
"Opposition Platform - For Life" = "#1170c7",
"Servant of the People" = "#25ad40")
# make plot
p2 <- ggplot(df1) +
geom_arcbar(aes(shares = Seats, r0 = 5, r1 = 10, fill = Party), color = "white", sep = 0.05) +
scale_fill_manual(values = colors) +
annotate("text",
label=paste0(round(248/450*100)," %"), x=-5.5, y=6, size=5, colour="white") +
annotate("text",
label=paste0(round(44/450*100)," %"), x=2, y=7.5, size=5, colour="white") +
annotate("text",
label=paste0(round(27/450*100)," %"), x=3.9, y=6.8, size=5, colour="white") +
annotate("text",
label=paste0(round(27/450*100)," %"), x=5.2, y=6, size=5, colour="white") +
annotate("text",
label=paste0(round(24/450*100)," %"), x=6.2, y=4.9, size=5, colour="white") +
annotate("text",
label=paste0(round(22/450*100)," %"), x=7.1, y=3.9, size=5, colour="white") +
annotate("text",
label=paste0(round(21/450*100)," %"), x=7.7, y=2.7, size=5, colour="white") +
annotate("text",
label=paste0(round(17/450*100)," %"), x=8, y=1.5, size=5, colour="white") +
annotate("text",
label=paste0(round(17/450*100)," %"), x=8.2, y=0.5, size=5, colour="white") +
coord_fixed() +
theme_void() +
labs(title = "Ukrainian Parliament of the 9th convocation",
subtitle = "The number and distribution of seats in the Verkhovna Rada of Ukraine",
caption = "Source: https://rada.gov.ua | DataVizStory, 2020") +
theme(title = element_text(size = 18),
plot.title = element_text(hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5),
plot.caption = element_text(vjust = -3, hjust = 0.9),
legend.position = 'bottom',
legend.direction = "horizontal",
legend.spacing.y = unit(0.1, "cm"),
legend.spacing.x = unit(0.1, "cm"),
legend.key.size = unit(0.8, 'lines'),
legend.text = element_text(margin = margin(r = 1, unit = 'cm')),
legend.text.align = 0) +
annotate("text", x = 0, y = 1, label = paste0("Seats in the Parliament :\n 423 (",423/450*100, "%) occupied \n 27 (",27/450*100,"%) vacant"), colour = "black", size = 6) +
guides(fill=guide_legend(nrow=3, byrow=TRUE, reverse=TRUE, title=NULL))
girafe(ggobj = p2, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
Various democratic countries use different processes to elect politicians. A few places use Mixed-member proportional (MMP) representation (Germany, New Zealand, Lesotho and Bolivia). In a MMP electoral system, voters have two votes: one for a representative for their electoral constituency and the other for a nation-wide political party. Seats are filled first by the constituency votes and then by political party. A party wins a certain number of seats based on the total vote percentage (a combination of both constituency votes and party votes). Sometimes a party does not win the number of constituencies needed to fill the total number of seats (i.e., they win 6 seats in total but are only elected to 4 constituencies). The remaining seats are known as overhang seats.
In 2017, the Bloomberg visual graphics team created an excellent data visualization of the German Bundestag prior to the 2017 German election. They represented the overhang seats by adding hollow seats to each party. We have decided to recreate the idea of hollow seats in ggparliament with geom_overhang_seats().
# Ref: https://cran.r-project.org/web/packages/ggparliament/vignettes/hanging_seats_7.html
# Ref: https://www.bloomberg.com/graphics/2017-how-germany-forms-government/
# data preparation
data <- election_data %>%
filter(country == "Germany" & year == "2013") %>% # on the federal level, CSU is a part of CDU
mutate(seats = gsub("255", "311", seats)) %>% # add the 56 CSU seats to CDU
mutate(seats = as.numeric(as.character(seats))) %>%
filter_all(all_vars(!grepl('Christian Social Union in Bavaria',.)))
# binary variable for overhang seat
overhangseats <- c(1, 0, 1, 0, 1, 0, 1, 0)
# number of overhang seats and remainder for each party
number_overhangseats <- c(3, 61, 3, 60,16, 295, 11, 182)
# expand data
german_data <- parliament_data(
election_data = data,
parl_rows = 11,
party_seats = data$seats,
type = "semicircle"
)
german_data <- german_data %>% mutate(overhang_seats = rep(overhangseats, number_overhangseats))
# make plot
german_parliament <- ggplot(german_data, aes(x,
y,
colour = party_short
)) +
geom_parliament_seats() +
# hollow the overhang seats as follows:
geom_overhang_seats(overhang_seats == 1) +
labs(
colour = "Party",
title = "German Bundestag - 2013 election",
subtitle = "Overhang seats are hollow."
) +
theme_void() +
theme(
plot.title = element_text(hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5),
legend.position = "none"
) +
draw_partylabels(type = "semicircle",
party_colours = colour,
party_names = party_short,
party_seats = seats) +
scale_colour_manual(
values = german_data$colour,
limits = german_data$party_short
)
girafe(ggobj = german_parliament, width_svg = 13, height_svg = 7,
options = list(opts_sizing(rescale = TRUE, width = 1.0)))
## [1] DataVizStory. _A Parliament Diagram in R_. DataVizStory, Nov. 2020.
## <URL: https://datavizstory.com/a-parliament-diagram-in-r/> (visited on
## 06/22/2021).
##
## [2] 1. U. NewsOne. _Ukrainian Parliament of the 9th convocation starts
## working_. 112.international, Aug. 2019. <URL:
## https://112.international/video/ukrainian-parliament-of-the-9th-convocation-starts-working-1284-1284.html>
## (visited on 06/22/2021).